package cn.com.chengmandian.core.tenant.utils;

import cn.com.chengmandian.core.common.constants.CommonConstant;
import cn.com.chengmandian.core.common.enums.ClientsEnum;
import cn.com.chengmandian.core.redis.cache.CacheHelper;
import cn.com.chengmandian.core.redis.service.RedisService;
import cn.com.chengmandian.core.tenant.TenantUtil;
import cn.com.chengmandian.core.tenant.pojo.LoginUser;
import cn.com.chengmandian.core.tenant.pojo.TenantInfo;
import cn.com.chengmandian.core.web.utils.SpringContextUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;

@Slf4j
@Component
public class AuthUtil {
    @Autowired
    private RedisService redisService;

    private static RedisService SRedisService;

    @PostConstruct
    public void init() {
        AuthUtil.SRedisService = redisService;
    }



    // 缓存用户token，用于防止重复登陆
    public static void putTenant(LoginUser loginUser, String secret, String token, Integer expireDay) {
        String key = CacheHelper.buildKey("CMD:WEB:TOKEN:" + secret + ":", loginUser.getId() + "");
        SRedisService.set(key, token, expireDay * 24 * 60 * 60);
    }

    // 缓存用户token，用于防止重复登陆
    public static void removeTenant(Integer userId, String secret, String token, Integer expireDay) {
        String key = CacheHelper.buildKey("CMD:WEB:TOKEN:" + secret + ":", userId + "");
        SRedisService.set(key, token, expireDay * 24 * 60 * 60);
    }

    // 检查用户是否重复登陆(20240709存在问题，没有区分用户类型)
    public static Boolean checkTenant(ClientsEnum client, LoginUser loginUser, HttpServletRequest request, String secret) {
        String key = CacheHelper.buildKey("CMD:WEB:TOKEN:" + secret + ":", loginUser.getId() + "");
        Object value = SRedisService.get(key);
        if (value == null || StrUtil.isEmpty(value.toString())) {
            return false;
        }
        String token = request.getHeader(client.getHeaderName());
        if (StrUtil.isEmpty(token) || !token.equals(value)) {
            return false;
        }
        return true;
    }

    /**
     * 获取用户信息
     */
    public static LoginUser getUser(String token, String tokenSecret) {
        if (!JWTUtil.verify(token, tokenSecret.getBytes())) {
            if (SpringContextUtil.isDev()) {
                log.error("Token验证未通过：{}", token);
            }
            return null;
        }
        JWT jwt = JWTUtil.parseToken(token);
        LoginUser user = jwt.getPayloads().toBean(LoginUser.class);
        if (user == null) return null;
        if (SpringContextUtil.isDev()) {
            log.info("Token：{}", JSONUtil.toJsonStr(user));
        }

        if (user.getExpireDate() < DateUtil.date().getTime()) {
            log.info("Token已过期：{}", token);
            return null;
        }
        return user;
    }

    public static LoginUser getUser(HttpServletRequest request, ClientsEnum client, String tokenSecret) {
        String token = request.getHeader(client.getHeaderName());
        if (StrUtil.isBlank(token)) return null;
        return getUser(request.getHeader(client.getHeaderName()), tokenSecret);
    }

    // 使用客户端密钥，谨慎使用，部分项目不适合
    public static LoginUser getUser(HttpServletRequest request, ClientsEnum client) {
        String token = request.getHeader(client.getHeaderName());
        if (StrUtil.isBlank(token)) return null;
        return getUser(request.getHeader(client.getHeaderName()), client.getSecret());
    }

    /**
     * 获取当前登陆用户
     * @return
     */
    public static LoginUser getUser() {
        HttpServletRequest request = ServletUtil.getRequest();
        if(request == null) return null;
        TenantInfo tenantInfo = TenantUtil.get();
        if (tenantInfo == null) return null;
        String clientId = request.getHeader(CommonConstant.HEADER_CLIENT_ID);
        if (StrUtil.isBlank(clientId)) return null;
        ClientsEnum client = ClientsEnum.codeOf(clientId);
        if (client == null) return null;
        return getUser(request, client, tenantInfo.getTokenSecret());
    }

    public static String get(String key) {
        LoginUser user = getUser();
        if (user.getAttrs() == null || !user.getAttrs().containsKey(key)) return null;
        return user.get(key);
    }
}
